import java.util.Iterator;

import junit.framework.TestCase;

import java.util.LinkedList;
import de.unibi.comet.util.LevelWiseIterator;
import de.unibi.comet.util.TreeNode;

public class LevelWiseIteratorTest extends TestCase {
	
	private class TestNode implements TreeNode {
		int nr;
		private LinkedList<TestNode> children;
		TestNode(int nr) {
			this.nr=nr;
			children = new LinkedList<TestNode>();
		}
		public void addChild(TestNode child) {
			children.add(child);
		}
		public Iterator<TestNode> children() {
			return children.iterator();
		}
		public boolean hasChild() {
			return children.size()>0;
		}
	}
	
	private TestNode[] nodes;
	
	@Override
	protected void setUp() throws Exception {
		nodes = new TestNode[10];
		for (int i=0; i<10; ++i) nodes[i] = new TestNode(i);
		nodes[0].addChild(nodes[1]);
		nodes[0].addChild(nodes[2]);
		nodes[0].addChild(nodes[3]);
		nodes[1].addChild(nodes[4]);
		nodes[3].addChild(nodes[5]);
		nodes[3].addChild(nodes[6]);
		nodes[4].addChild(nodes[7]);
		nodes[4].addChild(nodes[8]);
		nodes[4].addChild(nodes[9]);
	}

	public void testIterator() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0]);
		assertEquals(0, iter.next().nr);
		assertEquals(0, iter.getDepth());
		assertEquals(1, iter.next().nr);
		assertEquals(1, iter.getDepth());
		assertEquals(2, iter.next().nr);
		assertEquals(1, iter.getDepth());
		assertEquals(3, iter.next().nr);
		assertEquals(1, iter.getDepth());
		assertEquals(4, iter.next().nr);
		assertEquals(2, iter.getDepth());
		assertEquals(5, iter.next().nr);
		assertEquals(2, iter.getDepth());
		assertEquals(6, iter.next().nr);
		assertEquals(2, iter.getDepth());
		assertEquals(7, iter.next().nr);
		assertEquals(3, iter.getDepth());
		assertEquals(8, iter.next().nr);
		assertEquals(3, iter.getDepth());
		assertEquals(9, iter.next().nr);
		assertEquals(3, iter.getDepth());
		assertFalse(iter.hasNext());
	}
	
	public void testMinDepth1() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],1,-1);
		int i=1;
		while (iter.hasNext()) {
			assertEquals(i, iter.next().nr);
			i+=1;
		}
		assertEquals(10, i);
	}
	
	public void testMinDepth2() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],2,-1);
		assertEquals(4, iter.next().nr);
		assertEquals(5, iter.next().nr);
		assertEquals(6, iter.next().nr);
		assertEquals(7, iter.next().nr);
		assertEquals(8, iter.next().nr);
		assertEquals(9, iter.next().nr);
		assertFalse(iter.hasNext());
	}

	public void testMinDepth3() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],3,-1);
		assertEquals(7, iter.next().nr);
		assertEquals(8, iter.next().nr);
		assertEquals(9, iter.next().nr);
		assertFalse(iter.hasNext());
	}

	public void testMaxDepth1() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],-1,1);
		assertEquals(0, iter.next().nr);
		assertEquals(1, iter.next().nr);
		assertEquals(2, iter.next().nr);
		assertEquals(3, iter.next().nr);
		assertFalse(iter.hasNext());
	}

	public void testMaxDepth2() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],-1,2);
		assertEquals(0, iter.next().nr);
		assertEquals(1, iter.next().nr);
		assertEquals(2, iter.next().nr);
		assertEquals(3, iter.next().nr);
		assertEquals(4, iter.next().nr);
		assertEquals(5, iter.next().nr);
		assertEquals(6, iter.next().nr);
		assertFalse(iter.hasNext());
	}

	public void testMinMaxDepth1() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],1,2);
		assertEquals(1, iter.next().nr);
		assertEquals(2, iter.next().nr);
		assertEquals(3, iter.next().nr);
		assertEquals(4, iter.next().nr);
		assertEquals(5, iter.next().nr);
		assertEquals(6, iter.next().nr);
		assertFalse(iter.hasNext());
	}

	public void testMinMaxDepth2() {
		LevelWiseIterator<TestNode> iter = new LevelWiseIterator<TestNode>(nodes[0],2,2);
		assertEquals(4, iter.next().nr);
		assertEquals(5, iter.next().nr);
		assertEquals(6, iter.next().nr);
		assertFalse(iter.hasNext());
	}
	
}
